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 443760c64607220583d0b03e111eed726f359127..aceb28b6b38ac10364b6a3219d46174748132916 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,15 +5,11 @@ 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_; import org.zstack.sugonSdnController.controller.SugonSdnControllerGlobalProperty; -import org.zstack.sugonSdnController.controller.api.ApiConnector; -import org.zstack.sugonSdnController.controller.api.ApiConnectorFactory; -import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; -import org.zstack.sugonSdnController.controller.api.ObjectReference; +import org.zstack.sugonSdnController.controller.api.*; import org.zstack.sugonSdnController.controller.api.types.*; import org.zstack.utils.StringDSL; import org.zstack.utils.Utils; @@ -22,26 +18,32 @@ import org.zstack.utils.logging.CLogger; import java.io.IOException; import java.util.*; + public class TfPortClient { private static final CLogger logger = Utils.getLogger(TfPortClient.class); private ApiConnector apiConnector; + public TfPortClient(){ + apiConnector = getApiConnector(); + } + public ApiConnector getApiConnector() { - if (Objects.isNull(apiConnector)) { - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SdnControllerConstant.TF_CONTROLLER).find(); - apiConnector = ApiConnectorFactory.build(sdn.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT); + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq( + SdnControllerVO_.vendorType, + SdnControllerConstant.TF_CONTROLLER).find(); + if (sdn == null){ + throw new RuntimeException("Can not find a tf sdn controller."); + } + apiConnector = ApiConnectorFactory.build(sdn.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT); + if (apiConnector == null) { + throw new RuntimeException(String.format("Can not connect to tf sdn controller: %s.", sdn.getIp())); } return apiConnector; } - 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(); - portRequestContextEO.setOperation("CREATE"); - portRequestContextEO.setIs_admin("True"); - portRequestContextEO.setTenant_id(tenantId); + public TfPortResponse createPort(String l2Id, String l3Id, String mac, String ip, String tenantId, + String vmInventeryId, String tfPortUuid, String vmName) { TfPortRequestResource requestPortResourceEntity = new TfPortRequestResource(); requestPortResourceEntity.setNetworkId(l2Id); requestPortResourceEntity.setSubnetId(l3Id); @@ -55,153 +57,110 @@ public class TfPortClient { List ipEntities = new ArrayList<>(); ipEntities.add(ipEntity); requestPortResourceEntity.setFixdIps(ipEntities); - portRequestDataEO.setResource(requestPortResourceEntity); - portRequestBodyEO.setData(portRequestDataEO); - portRequestBodyEO.setContext(portRequestContextEO); - VirtualNetwork netObj; try { - netObj = networkRead(l2Id); - } catch (Exception e) { - throw new RuntimeException("NetworkNotFound: " + l2Id); - } - //if mac-address is specified, check against the exisitng ports - //to see if there exists a port with the same mac-address - if (!Objects.isNull(mac)) { - Map> macDict = new HashMap<>(); - List macList = new ArrayList<>(); - macList.add(mac); - macDict.put("mac_address", macList); - Map>> filters = new HashMap<>(); - filters.put("virtual_machine_interface_mac_addresses", macDict); - List ports; - try { - ports = virtualMachineInterfaceList(tenantId, filters); - } catch (IOException e) { - throw new RuntimeException(e); - } - ApiConnector apiConnector = getApiConnector(); - for (VirtualMachineInterface port : ports) { - VirtualMachineInterface byId; - try { - byId = (VirtualMachineInterface) (apiConnector != null ? apiConnector.findById(VirtualMachineInterface.class, port.getUuid()) : null); - } catch (IOException e) { - throw new RuntimeException(e); - } - MacAddressesType macAddressesType = null; - if (byId != null) { - macAddressesType = byId.getMacAddresses(); - } - List macAddresses = null; - if (macAddressesType != null) { - macAddresses = macAddressesType.getMacAddress(); - } - if (macAddresses != null) { - for (String macAddress : macAddresses) { - if (macAddress.equals(mac)) { - throw new RuntimeException("MacAddressInUse: " + mac); + VirtualNetwork netObj = (VirtualNetwork) apiConnector.findById(VirtualNetwork.class, l2Id); + if (netObj == null) { + throw new RuntimeException(String.format("Can not find tf virtualnetwork: %s.", l2Id)); + } + //if mac-address is specified, check against the exisitng ports + //to see if there exists a port with the same mac-address + if (!Objects.isNull(mac)) { + List ports = (List) apiConnector.list( + VirtualMachineInterface.class, Arrays.asList("default-domain", tenantId)); + + for (VirtualMachineInterface port : ports) { + VirtualMachineInterface byId = (VirtualMachineInterface) apiConnector.findById( + VirtualMachineInterface.class, port.getUuid()); + MacAddressesType macAddressesType = null; + if (byId != null && byId.getMacAddresses() != null) { + macAddressesType = byId.getMacAddresses(); + List macAddresses = macAddressesType.getMacAddress(); + for (String macAddress : macAddresses) { + if (macAddress.equals(mac)) { + throw new RuntimeException("MacAddressInUse: " + mac); + } } } } } - } - // initialize port object - VirtualMachineInterface port; - try { - port = portNeutronToVnc(requestPortResourceEntity, netObj, tfPortUuid); - } catch (IOException e) { - throw new RuntimeException(e); - } - 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 - if (apiConnector != null) { + // initialize port object + VirtualMachineInterface port; try { - apiConnector.create(port); + port = getTfPortObject(requestPortResourceEntity, netObj, tfPortUuid); } catch (IOException e) { throw new RuntimeException(e); } - } else { - throw new RuntimeException("can not create port~"); - } - // add support, nova boot --nic subnet-id=subnet_uuid - VirtualMachineInterface realPort; - try { - realPort = (VirtualMachineInterface) apiConnector.findById(VirtualMachineInterface.class, port.getUuid()); - } catch (IOException e) { - throw new RuntimeException(e); - } - if (requestPortResourceEntity.getFixdIps() != null && requestPortResourceEntity.getFixdIps().get(0).getIpAddress() != null) { - try { - portCreateInstanceIp(netObj, realPort, requestPortResourceEntity); - } catch (Exception e) { + PermType2 perms2 = new PermType2(); + perms2.setOwner(tenantId); + port.setPerms2(perms2); + port.setDisplayName(vmName); + // always request for v4 and v6 ip object and handle the failure + // create the object + Status result = apiConnector.create(port); + if (!result.isSuccess()) { + throw new RuntimeException(String.format("Failed to create tf VirtualMachineInterface: %s, reason: %s", + port.getUuid(), result.getMsg())); + } + // add support, nova boot --nic subnet-id=subnet_uuid + VirtualMachineInterface realPort = (VirtualMachineInterface) apiConnector.findById( + VirtualMachineInterface.class, port.getUuid()); + + if (ip != null) { try { - apiConnector.delete(realPort); - } catch (IOException ex) { - throw new RuntimeException(ex); + portCreateInstanceIp(netObj, realPort, l3Id, ip, tenantId); + } catch (Exception e) { + try { + apiConnector.delete(realPort); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + throw new RuntimeException(e); } - throw new RuntimeException(e); - } - } else if (netObj.getNetworkIpam() != null && netObj.getNetworkIpam().size() > 0) { - String errmsg = "Bad request trying to create IP instance."; - boolean ipv4PortDelete = false; - try { - portCreateInstanceIp(netObj, realPort, requestPortResourceEntity); // ipv4 - } catch (Exception e) { - ipv4PortDelete = true; - // failure in creating the instance ip. Roll back. + } else if (netObj.getNetworkIpam() != null && netObj.getNetworkIpam().size() > 0) { + String errmsg = "Bad request trying to create IP instance."; + boolean ipv4PortDelete = false; try { - apiConnector.delete(realPort); - } catch (IOException ex) { - throw new RuntimeException(ex); + Status ip_result = portCreateInstanceIp(netObj, realPort, l3Id, ip, tenantId); + if (!ip_result.isSuccess()) { + ipv4PortDelete = true; + logger.error("Tf instance ip create failed."); + } + } catch (Exception e) { + ipv4PortDelete = true; + // failure in creating the instance ip. Roll back. + try { + apiConnector.delete(realPort); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + throw new RuntimeException(errmsg); } - throw new RuntimeException(errmsg); - } - if (ipv4PortDelete) { - try { - apiConnector.delete(realPort); - } catch (IOException e) { - throw new RuntimeException(e); + if (ipv4PortDelete) { + try { + apiConnector.delete(realPort); + } catch (IOException e) { + throw new RuntimeException(e); + } } } - } - VirtualMachineInterface virtualMachineInterface; - try { - virtualMachineInterface = (VirtualMachineInterface) apiConnector.findById(VirtualMachineInterface.class, realPort.getUuid()); - } catch (IOException e) { - throw new RuntimeException(e); - } - try { - return portVncToNeutron(virtualMachineInterface); - } catch (IOException e) { - throw new RuntimeException(e); + VirtualMachineInterface newestPort = (VirtualMachineInterface) apiConnector.findById( + VirtualMachineInterface.class, realPort.getUuid()); + return getPortResponse(newestPort); + } catch (Exception e) { + throw new RuntimeException("TF api call failed: " + e); } } - private TfPortResponse portVncToNeutron(VirtualMachineInterface portObj) throws IOException { - ApiConnector apiConnector = getApiConnector(); + private TfPortResponse getPortResponse(VirtualMachineInterface portObj) throws IOException { TfPortResponse tfPortResponse = new TfPortResponse(); tfPortResponse.setPortId(portObj.getUuid()); tfPortResponse.setCode(200); tfPortResponse.setMacAddress(portObj.getMacAddresses().getMacAddress().get(0)); TfPortIpEntity ipEntity = new TfPortIpEntity(); - AllowedAddressPairs allowedAddressPairs = portObj.getAllowedAddressPairs(); - if (allowedAddressPairs != null && allowedAddressPairs.getAllowedAddressPair().size() > 0) { - for (AllowedAddressPair allowedAddressPair : allowedAddressPairs.getAllowedAddressPair()) { - allowedAddressPair.getIp().getIpPrefix(); - } - } List> ipBackRefs = portObj.getInstanceIpBackRefs(); if (ipBackRefs != null && ipBackRefs.size() > 0) { for (ObjectReference ipBackRef : ipBackRefs) { - String iipUuid = ipBackRef.getUuid(); - InstanceIp ipObj = null; - if (apiConnector != null) { - ipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, iipUuid); - } + InstanceIp ipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, ipBackRef.getUuid()); String ipAddr = ipObj != null ? ipObj.getAddress() : null; String subnetId = Objects.requireNonNull(ipObj).getSubnetUuid(); ipEntity.setIpAddress(ipAddr); @@ -213,73 +172,36 @@ public class TfPortClient { return tfPortResponse; } - private void portCreateInstanceIp(VirtualNetwork virtualNetwork, VirtualMachineInterface port, TfPortRequestResource requestPortResourceEntity) throws IOException { - // 1. find existing ips on port - // 2. add new ips on port from update body - // 3. delete old/stale ips on port - List> instanceIpBackRefs = port.getInstanceIpBackRefs(); - List fixdIps = requestPortResourceEntity.getFixdIps(); - Map staleIpIds = new HashMap<>(); - ApiConnector apiConnector = getApiConnector(); - if (Objects.nonNull(instanceIpBackRefs)) { - for (ObjectReference iip : instanceIpBackRefs) { - if (apiConnector != null) { - InstanceIp iipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, iip.getUuid()); - String ipaddr = iipObj.getAddress(); - staleIpIds.put(ipaddr, iip.getUuid()); - } - } - } - - String createdIipIds = ""; - for (TfPortIpEntity fixedIp : fixdIps) { - String ipaddr = fixedIp.getIpAddress(); - String ipFamily = "v4"; - if (ipaddr != null) { - // this ip survives to next gen - staleIpIds.remove(ipaddr); - - if (IPAddress.isValidIPv6(fixedIp.getIpAddress())) { - ipFamily = "v6"; - } - } - String subnetId = fixedIp.getSubnetId(); - // _self._create_instance_ip - String ipName = String.valueOf(UUID.randomUUID()); - InstanceIp ipObj = new InstanceIp(); - ipObj.setUuid(ipName); - if (subnetId != null) { - ipObj.setSubnetUuid(subnetId); - } - ipObj.setVirtualMachineInterface(port); - ipObj.setVirtualNetwork(virtualNetwork); - ipObj.setFamily(ipFamily); - if (ipaddr != null) { - ipObj.setAddress(ipaddr); - } - // set instance ip ownership to real tenant - PermType2 permType2 = new PermType2(); - String tenantId = requestPortResourceEntity.getTenantId(); - permType2.setOwner(tenantId); - ipObj.setPerms2(permType2); - - List fqName = virtualNetwork.getQualifiedName(); - fqName.add(ipName); - ipObj.setName(ipName); - - if (apiConnector != null) { - apiConnector.create(ipObj); // ipName is id - } - createdIipIds.concat(ipName); - } - for (String key : staleIpIds.keySet()) { - apiConnector.delete(InstanceIp.class, staleIpIds.get(key)); - } + private Status portCreateInstanceIp(VirtualNetwork virtualNetwork, VirtualMachineInterface port, + String subnetId, String ip, String tenantId) throws IOException { + InstanceIp ipObj = new InstanceIp(); + String ipFamily = "v4"; + if (ip != null) { + if (IPAddress.isValidIPv6(ip)) { + ipFamily = "v6"; + } + ipObj.setAddress(ip); + } + + String ipName = String.valueOf(UUID.randomUUID()); + ipObj.setUuid(ipName); + ipObj.setName(ipName); + ipObj.setSubnetUuid(subnetId); + ipObj.setVirtualMachineInterface(port); + List fqName = virtualNetwork.getQualifiedName(); + fqName.add(ipName); + ipObj.setVirtualNetwork(virtualNetwork); + ipObj.setFamily(ipFamily); + // set instance ip ownership to real tenant + PermType2 permType2 = new PermType2(); + permType2.setOwner(tenantId); + ipObj.setPerms2(permType2); + return apiConnector.create(ipObj); } - private VirtualMachineInterface portNeutronToVnc(TfPortRequestResource requestPortResourceEntity, VirtualNetwork virtualNetwork, String tfPortUUid) throws IOException { + private VirtualMachineInterface getTfPortObject(TfPortRequestResource requestPortResourceEntity, VirtualNetwork virtualNetwork, String tfPortUUid) throws IOException { String projectId = requestPortResourceEntity.getTenantId(); - Project projectObj = getProjectObj(requestPortResourceEntity); + Project projectObj = (Project) apiConnector.findById(Project.class, projectId); IdPermsType idPermsType = new IdPermsType(); idPermsType.setEnable(true); String portUuid = String.valueOf(UUID.randomUUID()); @@ -298,96 +220,47 @@ public class TfPortClient { portObj.setMacAddresses(macAddressesType); } if (requestPortResourceEntity.getDeviceId() != null) { - List> vmRefs = portObj.getVirtualMachine(); - List> deleteVmList = new ArrayList<>(); - if (Objects.nonNull(vmRefs)) { - for (ObjectReference vmRef : vmRefs) { - if (!vmRef.getReferredName().get(0).equals(requestPortResourceEntity.getDeviceId())) { - deleteVmList.add(vmRef); - } - } - } - if (requestPortResourceEntity.getDeviceId() != null) { - try { - VirtualMachine instanceObj = ensureInstanceExists(requestPortResourceEntity.getDeviceId(), projectId, false); - portObj.setVirtualMachine(instanceObj); - } catch (Exception e) { - throw new RuntimeException("BadRequest port."); - } - } - if (deleteVmList.size() > 0) { - ApiConnector apiConnector = getApiConnector(); - if (apiConnector != null) { - apiConnector.update(portObj); - } - for (ObjectReference vmRef : vmRefs) { - if (apiConnector != null) { - apiConnector.delete(VirtualMachine.class, vmRef.getUuid()); - } - } - } + VirtualMachine instanceObj = ensureInstanceExists(requestPortResourceEntity.getDeviceId(), projectId, false); + portObj.setVirtualMachine(instanceObj); } - if (Objects.nonNull(requestPortResourceEntity.getFixdIps()) && Objects.nonNull(requestPortResourceEntity.getFixdIps().get(0).getIpAddress())) { + String fixIp = requestPortResourceEntity.getFixdIps() == null ? null: requestPortResourceEntity.getFixdIps().get(0).getIpAddress(); + if (Objects.nonNull(fixIp)) { String netId = requestPortResourceEntity.getNetworkId(); - String portObjIps = ""; - for (TfPortIpEntity fixedIp : requestPortResourceEntity.getFixdIps()) { - if (Objects.nonNull(fixedIp.getIpAddress())) { - //read instance ip addrs on port only once - if (portObjIps.length() == 0) { - List> ipBackRefs = portObj.getInstanceIpBackRefs(); - if (ipBackRefs != null && ipBackRefs.size() > 0) { - for (ObjectReference ipBackRef : ipBackRefs) { - try { - ApiConnector apiConnector = getApiConnector(); - InstanceIp ipObj = null; - if (apiConnector != null) { - ipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, ipBackRef.getUuid()); - } - portObjIps.concat(ipObj != null ? ipObj.getAddress() : null); - } catch (Exception ignored) { - } - } - } - } - String ipAddr = fixedIp.getIpAddress(); - if (portObjIps.contains(ipAddr)) { - continue; - } - if (ipAddrInNetId(ipAddr, netId)) { - throw new RuntimeException("IpAddressInUse"); - } - } + if (ipInUseCheck(fixIp, netId)) { + throw new RuntimeException("IpAddressInUse: " + fixIp); } } return portObj; } - public boolean ipAddrInNetId(String ipAddr, String netId) throws IOException { - ApiConnector apiConnector = getApiConnector(); - - if (apiConnector != null) { - 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; - } + public boolean ipInUseCheck(String ipAddr, String netId) throws IOException { + 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; } } } } } + return false; } private VirtualMachine ensureInstanceExists(String deviceId, String projectId, boolean baremeetal) throws IOException { - VirtualMachine instanceObj = new VirtualMachine(); + VirtualMachine instanceObj = null; try { + instanceObj = (VirtualMachine) apiConnector.findById(VirtualMachine.class, deviceId); + if (instanceObj != null) { + return instanceObj; + } + instanceObj = new VirtualMachine(); instanceObj.setName(deviceId); instanceObj.setUuid(deviceId); PermType2 permType2 = new PermType2(); @@ -398,25 +271,14 @@ public class TfPortClient { } else { instanceObj.setServerType("virtual-server"); } - ApiConnector apiConnector = getApiConnector(); - if (apiConnector != null) { - try { - apiConnector.create(instanceObj); - } catch (Exception e) { - throw new RuntimeException("can not create VirtualMachine~"); - } - } + apiConnector.create(instanceObj); } catch (Exception e) { // Exception...... - ApiConnector apiConnector = getApiConnector(); VirtualMachine dbInstanceObj = null; if (instanceObj.getUuid() != null) { - if (apiConnector != null) { - dbInstanceObj = (VirtualMachine) apiConnector.findById(VirtualMachine.class, instanceObj.getUuid()); - } + dbInstanceObj = (VirtualMachine) apiConnector.findById(VirtualMachine.class, instanceObj.getUuid()); } else { - if (apiConnector != null) { - dbInstanceObj = (VirtualMachine) apiConnector.findByFQN(VirtualMachine.class, instanceObj.getName()); - } + dbInstanceObj = (VirtualMachine) apiConnector.findByFQN(VirtualMachine.class, instanceObj.getName()); + } if (dbInstanceObj != null) { if (baremeetal && !Objects.equals(dbInstanceObj.getServerType(), "baremetal-server")) { @@ -429,32 +291,12 @@ public class TfPortClient { return instanceObj; } - private Project getProjectObj(TfPortRequestResource requestPortResourceEntity) throws IOException { - ApiConnector apiConnector = getApiConnector(); - - if (apiConnector != null) { - return (Project) apiConnector.findById(Project.class, requestPortResourceEntity.getTenantId()); - } else { - throw new RuntimeException("can not get project~"); - } - } - - private List virtualMachineInterfaceList(String tenantId, Map>> filters) throws IOException { - ApiConnector apiConnector = getApiConnector(); - - if (apiConnector != null) { - return (List) apiConnector.list(VirtualMachineInterface.class, Arrays.asList("default-domain", tenantId)); - } else { - throw new RuntimeException("can not get apiConnector~"); - } - - } - public TfPortResponse getVirtualMachineInterface(String portId) { try { - VirtualMachineInterface port = (VirtualMachineInterface) getApiConnector().findById(VirtualMachineInterface.class, portId); + VirtualMachineInterface port = (VirtualMachineInterface) getApiConnector().findById( + VirtualMachineInterface.class, portId); if (port != null){ - return portVncToNeutron(port); + return getPortResponse(port); }else { return null; } @@ -463,179 +305,86 @@ public class TfPortClient { } } - private VirtualNetwork networkRead(String l2Id) throws IOException { - return virtualNetworkRead(l2Id); - } - - private VirtualNetwork virtualNetworkRead(String l2Id) throws IOException { - ApiConnector apiConnector = getApiConnector(); - if (apiConnector != null) { - return (VirtualNetwork) apiConnector.findById(VirtualNetwork.class, l2Id); - } else { - throw new RuntimeException("can not get apiConnector~"); - } - } - - public TfPortResponse deletePort(String portId, String accountId) { + public TfPortResponse deletePort(String portId) { TfPortResponse response = new TfPortResponse(); - TfPortRequestBody portRequestBodyEO = new TfPortRequestBody(); - TfPortRequestData portRequestDataEO = new TfPortRequestData(); - TfPortRequestContext portRequestContextEO = new TfPortRequestContext(); - portRequestContextEO.setOperation("DELETE"); - portRequestContextEO.setIs_admin("True"); - portRequestContextEO.setTenant_id(accountId); - portRequestDataEO.setId(portId); - portRequestBodyEO.setData(portRequestDataEO); - portRequestBodyEO.setContext(portRequestContextEO); -// begin - ApiConnector apiConnector = getApiConnector(); - VirtualMachineInterface portObj = null; try { - if (apiConnector != null) { - portObj = (VirtualMachineInterface) apiConnector.findById(VirtualMachineInterface.class, portId); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - String instanceId; - if (Objects.equals(portObj.getParentType(), "virtual-machine")) { - instanceId = portObj.getParentUuid(); - } else { - List> vmRefs = portObj.getVirtualMachine(); - if (vmRefs != null && vmRefs.size() > 0) { - instanceId = vmRefs.get(0).getUuid(); - } else { - instanceId = null; - } - } - - List> routerBackRefs = portObj.getLogicalRouterBackRefs(); - if (routerBackRefs != null && routerBackRefs.size() > 0) { - throw new RuntimeException("Port In Use~"); - } - // release instance IP address - List> iipBackRefs = portObj.getInstanceIpBackRefs(); - if (iipBackRefs != null && iipBackRefs.size() > 0) { - for (ObjectReference iipBackRef : iipBackRefs) { - InstanceIp iipObj = null; - try { - if (apiConnector != null) { - iipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, iipBackRef.getUuid()); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - // in case of shared ip only delete the link to the VMI - if (iipObj != null) { - iipObj.removeVirtualMachineInterface(portObj); - } - List> virtualMachineInterface = iipObj != null ? iipObj.getVirtualMachineInterface() : null; - if (virtualMachineInterface == null || virtualMachineInterface.size() == 0) { - try { - if (apiConnector != null) { - apiConnector.delete(InstanceIp.class, iipBackRef.getUuid()); - } - } catch (Exception e) { - try { + VirtualMachineInterface portObj = (VirtualMachineInterface) apiConnector.findById(VirtualMachineInterface.class, portId); + if (portObj == null) { + response.setCode(200); + return response; + } + // release instance IP address + List> iipBackRefs = portObj.getInstanceIpBackRefs(); + if (iipBackRefs != null && iipBackRefs.size() > 0) { + for (ObjectReference iipBackRef : iipBackRefs) { + InstanceIp iipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, iipBackRef.getUuid()); + // in case of shared ip only delete the link to the VMI + if (iipObj != null) { + iipObj.removeVirtualMachineInterface(portObj); + List> virtualMachineInterface = iipObj.getVirtualMachineInterface(); + if (virtualMachineInterface == null || virtualMachineInterface.size() == 0) { + Status delResult = apiConnector.delete(InstanceIp.class, iipBackRef.getUuid()); + if (!delResult.isSuccess()) { + throw new RuntimeException("Tf instance ip delete failed: " + iipBackRef.getUuid()); + } + } else { apiConnector.update(iipObj); - } catch (IOException ex) { - throw new RuntimeException(ex); } } - } else { - try { - apiConnector.update(iipObj); - } catch (IOException e) { - throw new RuntimeException(e); - } } } - } - // disassociate any floating IP used by instance - - List> fipBackRefs = portObj.getFloatingIpBackRefs(); - if (CollectionUtils.isNotEmpty(fipBackRefs)) { - for (ObjectReference fipBackRef : fipBackRefs) { - try { - floatingipUpdate(fipBackRef.getUuid()); - } catch (IOException e) { - throw new RuntimeException(e); + // disassociate any floating IP used by instance + List> fipBackRefs = portObj.getFloatingIpBackRefs(); + if (CollectionUtils.isNotEmpty(fipBackRefs)) { + for (ObjectReference fipBackRef : fipBackRefs) { + FloatingIp fipObj = getTfFloatingipObject(fipBackRef.getUuid()); + if (fipObj != null) { + apiConnector.update(fipObj); + } } } - } - try { - if (apiConnector != null) { - apiConnector.delete(VirtualMachineInterface.class, portId); + apiConnector.delete(VirtualMachineInterface.class, portId); + // delete VirtualMachine if this was the last port + String instanceId; + if (Objects.equals(portObj.getParentType(), "virtual-machine")) { + instanceId = portObj.getParentUuid(); + } else { + List> vmRefs = portObj.getVirtualMachine(); + if (vmRefs != null && vmRefs.size() > 0) { + instanceId = vmRefs.get(0).getUuid(); + } else { + instanceId = null; + } } - } catch (IOException e) { - throw new RuntimeException(e); - } - - // delete instance if this was the last port - if (instanceId != null) { - try { - if (apiConnector != null) { + if (instanceId != null) { + VirtualMachine vm = (VirtualMachine) apiConnector.findById(VirtualMachine.class, instanceId); + if (CollectionUtils.isEmpty(vm.getVirtualMachineInterfaceBackRefs())) { apiConnector.delete(VirtualMachine.class, instanceId); } - } catch (IOException e) { - throw new RuntimeException(e); } - } - response.setCode(200); - return response; - // end - } + response.setCode(200); + return response; - private void floatingipUpdate(String uuid) throws IOException { - FloatingIp fipObj = floatingipNeutronToVnc(uuid); - apiConnector.update(fipObj); + } catch (Exception e) { + response.setCode(500); + response.setMsg(String.format("Delete tf virtualMachineInterface %s failed, reason: %s", + portId, e.getMessage())); + return response; + } } - private FloatingIp floatingipNeutronToVnc(String uuid) throws IOException { + private FloatingIp getTfFloatingipObject(String uuid) throws IOException { FloatingIp fipObj = (FloatingIp) apiConnector.findById(FloatingIp.class, uuid); - List> portRefs = fipObj.getVirtualMachineInterface(); - fipObj.clearVirtualMachineInterface(); - if (CollectionUtils.isEmpty(portRefs)){ - fipObj.setFixedIpAddress(null); - } else { - VirtualMachineInterface portObj = (VirtualMachineInterface) apiConnector.findById(VirtualMachineInterface.class, portRefs.get(0).getUuid()); - List> iipRefs = portObj.getInstanceIpBackRefs(); - if (CollectionUtils.isNotEmpty(iipRefs) && iipRefs.size() > 1) { - String msg = "Port " + portObj.getUuid() + " has multiple fixed IP addresses. Must provide a specific IP address when assigning a floating IP."; - throw new RuntimeException(msg); - } - if (CollectionUtils.isNotEmpty(iipRefs)){ - InstanceIp iipObj = (InstanceIp) apiConnector.findById(InstanceIp.class, iipRefs.get(0).getUuid()); - checkPortFipAssoc(portObj, iipObj.getAddress(), fipObj); - fipObj.setFixedIpAddress(iipObj.getAddress()); - } + if (fipObj == null) { + return null; } + fipObj.clearVirtualMachineInterface(); + fipObj.setFixedIpAddress(null); return fipObj; } - private void checkPortFipAssoc(VirtualMachineInterface portObj, String address, FloatingIp fipObj) throws IOException { - // check if port already has floating ip associated - List> fipRefs = portObj.getFloatingIpBackRefs(); - List fipIds = new ArrayList<>(); - if (CollectionUtils.isNotEmpty(fipRefs)) { - for (ObjectReference ref : fipRefs) { - if (!Objects.equals(fipObj.getUuid(), ref.getUuid())) { - fipIds.add(ref.getUuid()); - } - } - } - if (CollectionUtils.isNotEmpty(fipIds)) { - for (String fipId : fipIds) { - FloatingIp fipInstance = (FloatingIp) apiConnector.findById(FloatingIp.class, fipId); - if (fipInstance.getFixedIpAddress().equals(address)) { - throw new RuntimeException("FloatingIPPortAlreadyAssociated: " + fipInstance.getAddress() + " && " + portObj); - } - } - } - } - /** * 检查ip是否在已经被占用 * @@ -644,16 +393,15 @@ public class TfPortClient { * @return 占用-true; 未占用-false */ public boolean checkTfIpAvailability(String ipAddr, String subnetId) throws IOException { - ApiConnector apiConnector = getApiConnector(); - VirtualNetwork virtualNetwork = null; L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, subnetId).find(); - virtualNetwork = (VirtualNetwork) apiConnector.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3Network.getL2NetworkUuid())); - List> instanceIpBackRefs = null; - List> subnetListRefs = null; - if (Objects.nonNull(virtualNetwork)) { - instanceIpBackRefs = virtualNetwork.getInstanceIpBackRefs(); - subnetListRefs = virtualNetwork.getNetworkIpam(); + VirtualNetwork virtualNetwork = (VirtualNetwork) apiConnector.findById( + VirtualNetwork.class, StringDSL.transToTfUuid(l3Network.getL2NetworkUuid())); + + if (Objects.isNull(virtualNetwork)) { + return false; } + List> instanceIpBackRefs = virtualNetwork.getInstanceIpBackRefs(); + List> subnetListRefs = virtualNetwork.getNetworkIpam(); if (Objects.nonNull(virtualNetwork.getRouterExternal()) && virtualNetwork.getRouterExternal()) { // if external network, floating ips. @@ -673,15 +421,14 @@ public class TfPortClient { } } } else { // else instance ips. - List ipObjects = null; - if (Objects.nonNull(apiConnector) && CollectionUtils.isNotEmpty(instanceIpBackRefs)) { - ipObjects = (List) apiConnector.getObjects(InstanceIp.class, instanceIpBackRefs); - } - // check all instance ips. - if (CollectionUtils.isNotEmpty(ipObjects)) { - for (InstanceIp ipObj : ipObjects) { - if (ipObj.getAddress().equals(ipAddr)) { - return true; + if (CollectionUtils.isNotEmpty(instanceIpBackRefs)) { + List ipObjects = (List) apiConnector.getObjects(InstanceIp.class, instanceIpBackRefs); + // check all instance ips. + if (CollectionUtils.isNotEmpty(ipObjects)) { + for (InstanceIp ipObj : ipObjects) { + if (ipObj.getAddress().equals(ipAddr)) { + return true; + } } } } @@ -726,21 +473,17 @@ public class TfPortClient { return false; } - public List listUsedIps(String networkUuid, String SubnetUuid) { - List tfPortIpEntityList = new ArrayList<>(); - - - return tfPortIpEntityList; - } - public void updateTfPort(String tfPortUUid, String accountId, String deviceId) { try { - VirtualMachineInterface port = (VirtualMachineInterface) getApiConnector().findById(VirtualMachineInterface.class, tfPortUUid); + VirtualMachineInterface port = (VirtualMachineInterface) apiConnector.findById( + VirtualMachineInterface.class, tfPortUUid); VirtualMachine vm = ensureInstanceExists(deviceId, accountId, false); port.setVirtualMachine(vm); - getApiConnector().update(port); + apiConnector.update(port); } catch (IOException e) { throw new RuntimeException(e); } } } + + diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java index f8753453ab7a8a93a2028bbc5519ff91caef6fe1..c6ee8351ed7d59f49e2ee99b938a1af2008b26a0 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java @@ -1,6 +1,8 @@ package org.zstack.sugonSdnController.network; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; import org.zstack.sugonSdnController.controller.SugonSdnController; import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; import org.zstack.core.db.Q; @@ -18,6 +20,7 @@ import org.zstack.sdnController.header.SdnControllerVO; import org.zstack.sdnController.header.SdnControllerVO_; import static org.zstack.core.Platform.err; +import static org.zstack.core.Platform.operr; public class TfL2Network extends L2NoVlanNetwork implements TfL2NetworkExtensionPoint{ @@ -190,6 +193,13 @@ public class TfL2Network extends L2NoVlanNetwork implements TfL2NetworkExtension private void handle(APIDeleteL2NetworkMsg msg) { APIDeleteL2NetworkEvent evt = new APIDeleteL2NetworkEvent(msg.getId()); + if(Q.New(L3NetworkVO.class).eq(L3NetworkVO_.l2NetworkUuid, msg.getL2NetworkUuid()).count() > 0){ + String error = String.format("L2Network[%s] still has some L3Networks, please delete L3Networks first.", + msg.getL2NetworkUuid()); + evt.setError(operr(error)); + bus.publish(evt); + return; + } deleteTfL2NetworkOnSdnController(self, new Completion(msg) { @Override public void success() { 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 index fd8e7733256e4b124f1dbe298db59e32010fa6e1..24bf1e8ff9326383c6d63036bb81f9185a09a33f 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java @@ -31,8 +31,10 @@ public class TfNicManageExtensionPointImpl implements NicManageExtensionPoint { nic.setType(VmInstanceConstant.TF_VIRTUAL_NIC_TYPE); TfPortResponse port = null; String portUuid = msg.getResourceUuid(); + String tfPortUuid = null; if (portUuid != null){ - port = tfPortService.getTfPort(StringDSL.transToTfUuid(portUuid)); + tfPortUuid = StringDSL.transToTfUuid(portUuid); + port = tfPortService.getTfPort(tfPortUuid); if (port != null){ String ipAddr = null; for (TfPortIpEntity ipEntrty: port.getFixedIps()) { @@ -52,7 +54,7 @@ public class TfNicManageExtensionPointImpl implements NicManageExtensionPoint { } if (port == null) { String l2NetworkUuid = l3Network.getL2NetworkUuid(); - port = tfPortService.createTfPort(StringDSL.transToTfUuid(portUuid), l2NetworkUuid, msg.getL3NetworkUuid(), + port = tfPortService.createTfPort(tfPortUuid, l2NetworkUuid, msg.getL3NetworkUuid(), nic.getMac(), msg.getIp()); logger.debug("Create a new tf port success."); } 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 fdf5a2d3f791f6000abaecc42641f2e6a4c4722a..6173846866b7eb70c635e37b5d3884674c69fcab 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 @@ -62,10 +62,9 @@ public class TfPortService { } 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); + return tfPortClient.deletePort(tfPortUUid); } public void updateTfPort(String tfPortUUid, String vmUuid) { diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java index 20347a1448f9d8a2eb5d98aff68085c9f9af5f6f..e01eeb21f6f76fa86dd81d091d69664c80c33bc4 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java @@ -45,7 +45,7 @@ public class VmDetachNicExtensionPointImpl implements VmDetachNicExtensionPoint, L3NetworkVO l3nw = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); if (SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3nw.getType())) { // bug fix: won't delete nic related tags, because recovery flow will use them - deleteTfPort(nic.getUuid(), nic.getL3NetworkUuid()); + deleteTfPort(nic.getUuid()); } } @@ -59,16 +59,15 @@ public class VmDetachNicExtensionPointImpl implements VmDetachNicExtensionPoint, CustomNicOperator nicOperator = new CustomNicOperator(vm.getUuid(), l3.getUuid()); String customNicId = nicOperator.getCustomNicId(); nicOperator.deleteNicTags(); - deleteTfPort(customNicId, l3.getUuid()); + deleteTfPort(customNicId); } } - private void deleteTfPort(String nicUuid, String l3NetworkUuid) { + private void deleteTfPort(String nicUuid) { TfPortClient client = new TfPortClient(); - String accountId = accountMgr.getOwnerAccountUuidOfResource(l3NetworkUuid); - TfPortResponse response = client.deletePort(StringDSL.transToTfUuid(nicUuid), accountId); + TfPortResponse response = client.deletePort(StringDSL.transToTfUuid(nicUuid)); if (response.getCode() != HttpStatus.OK.value()) { throw new RuntimeException("failed to invoke deleting tf port: " + response); }