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 e10c9533c2e5fd4ad5494ac4e04219ad2a7678c9..15587b41676abb133ca52bb10558a7471349f109 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 @@ -1,6 +1,7 @@ package org.zstack.sugonSdnController.controller; import org.apache.commons.lang.StringUtils; +import org.apache.commons.net.util.SubnetUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.db.Q; @@ -23,14 +24,13 @@ import org.zstack.sugonSdnController.header.APICreateL2TfNetworkMsg; import org.zstack.utils.StringDSL; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import static org.zstack.core.Platform.operr; +import static org.zstack.utils.network.NetworkUtils.getSubnetInfo; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class SugonSdnController implements TfSdnController, SdnController { @@ -305,6 +305,9 @@ public class SugonSdnController implements TfSdnController, SdnController { if (opCheck.isPresent()) { // 移除指定的三层子网 vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().remove(opCheck.get()); + if(vn.getNetworkIpam().get(0).getAttr().getIpamSubnets()==null||vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().size()==0){ + vn.getNetworkIpam().clear(); + } } // 更新 tf 网络信息 Status status = apiConnector.update(vn); @@ -398,10 +401,19 @@ public class SugonSdnController implements TfSdnController, SdnController { ipamSubnetType.setSubnet(subnetType); // subnet_name ipamSubnetType.setSubnetName(l3NetworkVO.getName()); + // 特殊IP定义 + SubnetUtils.SubnetInfo subnetInfo = getSubnetInfo(new SubnetUtils(msg.getNetworkCidr())); + String gatewayIp = subnetInfo.getLowAddress(); + String serviceIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getLowAddress())+1); + String startIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getLowAddress())+2); + String endIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getHighAddress())-1); // DNS -> 查询zstack数据库 List dns = Q.New(L3NetworkDnsVO.class).eq(L3NetworkDnsVO_.l3NetworkUuid, l3NetworkVO.getUuid()).list(); if(dns!=null&&dns.size()>0){ ipamSubnetType.setDnsServerAddress(dns.get(0).getDns()); + } else{ + // 设置默认DnsServerAddress + ipamSubnetType.setDnsServerAddress(serviceIp); } // host_route -> 查询zstack数据库 List hostRoutes = Q.New(L3NetworkHostRouteVO.class).eq(L3NetworkHostRouteVO_.l3NetworkUuid, l3NetworkVO.getUuid()).list(); @@ -413,6 +425,12 @@ public class SugonSdnController implements TfSdnController, SdnController { ipamSubnetType.setHostRoutes(routeTableType); } ipamSubnetType.setEnableDhcp(getEnableDHCPFlag(l3NetworkVO.getUuid())); + + // 设置默认网关 + ipamSubnetType.setDefaultGateway(gatewayIp); + // 设置可分配IP池范围 + AllocationPoolType allocationPoolType = new AllocationPoolType(startIp,endIp); + ipamSubnetType.addAllocationPools(allocationPoolType); // 封装实体 -> ObjectReference IpamSubnets ipamSubnets = new IpamSubnets(); ipamSubnets.addSubnets(ipamSubnetType); @@ -563,7 +581,22 @@ public class SugonSdnController implements TfSdnController, SdnController { .filter(m->StringDSL.transToTfUuid(l3NetworkVO.getUuid()).equals(m.getSubnetUuid())) .findFirst(); if(checkOp.isPresent()){ - checkOp.get().setDnsServerAddress(msg.getDns()); + DhcpOptionsListType type = checkOp.get().getDhcpOptionList(); + if(type!=null){ + String currDhcpValue = type.getDhcpOption().get(0).getDhcpOptionValue(); + if(StringUtils.isNotEmpty(currDhcpValue)){ + type.getDhcpOption().get(0).setDhcpOptionValue(currDhcpValue+" "+ msg.getDns()); + } else{ + type.getDhcpOption().get(0).setDhcpOptionValue(msg.getDns()); + } + } else{ + DhcpOptionsListType dhcpOptionsListType = new DhcpOptionsListType(); + DhcpOptionType dhcpOptionType = new DhcpOptionType(); + dhcpOptionType.setDhcpOptionValue(msg.getDns()); + dhcpOptionType.setDhcpOptionName("6"); + dhcpOptionsListType.addDhcpOption(dhcpOptionType); + checkOp.get().setDhcpOptionList(dhcpOptionsListType); + } // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ @@ -605,20 +638,16 @@ public class SugonSdnController implements TfSdnController, SdnController { .findFirst(); if(checkOp.isPresent()){ // 子网存在 - IpamSubnetType type = checkOp.get(); - // 判断删除的dns和子网的dns是否一致 - if(type.getDnsServerAddress().equals(msg.getDns())) { - String defaultDns = type.getDefaultGateway().substring(0, type.getDefaultGateway().lastIndexOf(".")) + ".253"; - checkOp.get().setDnsServerAddress(defaultDns); - // 更新 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")); - } else { - completion.success(); - } - } else{ - completion.fail(operr("delete dns from to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"error dns address")); + String dnsValue = checkOp.get().getDhcpOptionList().getDhcpOption().get(0).getDhcpOptionValue(); + List dnsValues = new ArrayList<>(Arrays.asList(dnsValue.split(" "))); + dnsValues.remove(msg.getDns()); + checkOp.get().getDhcpOptionList().getDhcpOption().get(0).setDhcpOptionValue(StringUtils.join(dnsValues, " ")); + // 更新 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")); + } else { + completion.success(); } } // 未找到指定的子网,继续执行后续的zstack逻辑 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 34b11919ba3f4e245cc405dae46d41370ff7e928..4f24bb472a1fc72bfbfa9aa26bd5d7e0ab651536 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 @@ -1,6 +1,10 @@ package org.zstack.sugonSdnController.network; +import org.apache.commons.net.util.SubnetUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; import org.zstack.sugonSdnController.controller.SugonSdnController; import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; import org.zstack.core.db.Q; @@ -16,8 +20,11 @@ import org.zstack.sdnController.header.SdnControllerVO; import org.zstack.sdnController.header.SdnControllerVO_; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.NetworkUtils; import static org.zstack.core.Platform.err; +import static org.zstack.utils.network.NetworkUtils.getSubnetInfo; /** * @description: @@ -29,6 +36,9 @@ public class TfL3Network extends L3BasicNetwork { @Autowired SdnControllerManager sdnControllerManager; + @Autowired + protected DatabaseFacade dbf; + public TfL3Network(L3NetworkVO self) { super(self); } @@ -58,7 +68,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIDeleteL3NetworkMsg msg){ APIDeleteL3NetworkEvent evt = new APIDeleteL3NetworkEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -67,7 +77,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.deleteL3Network(l3Network, new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); } @@ -86,7 +96,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIUpdateL3NetworkMsg msg){ APIUpdateL3NetworkEvent evt = new APIUpdateL3NetworkEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -95,7 +105,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.updateL3Network(l3Network,msg, new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); } @@ -115,7 +125,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIAddIpRangeByNetworkCidrMsg msg){ APIAddIpRangeByNetworkCidrEvent evt = new APIAddIpRangeByNetworkCidrEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -124,8 +134,9 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.addL3IpRangeByCidr(l3Network,msg, new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); + procReservedIP(msg); } @Override @@ -142,7 +153,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIDeleteIpRangeMsg msg){ APIDeleteIpRangeEvent evt = new APIDeleteIpRangeEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -151,7 +162,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.deleteL3Network(l3Network, new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); } @@ -170,7 +181,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIAddDnsToL3NetworkMsg msg){ APIAddDnsToL3NetworkEvent evt = new APIAddDnsToL3NetworkEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -179,7 +190,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.addL3Dns(l3Network, msg,new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); } @@ -198,7 +209,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIRemoveDnsFromL3NetworkMsg msg){ APIRemoveDnsFromL3NetworkEvent evt = new APIRemoveDnsFromL3NetworkEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -207,7 +218,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.deleteL3Dns(l3Network, msg,new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); } @@ -226,7 +237,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIAddHostRouteToL3NetworkMsg msg){ APIAddHostRouteToL3NetworkEvent evt = new APIAddHostRouteToL3NetworkEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -235,7 +246,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.addL3HostRoute(l3Network, msg,new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); } @@ -254,7 +265,7 @@ public class TfL3Network extends L3BasicNetwork { private void handle(APIRemoveHostRouteFromL3NetworkMsg msg){ APIRemoveHostRouteFromL3NetworkEvent evt = new APIRemoveHostRouteFromL3NetworkEvent(msg.getId()); - // 查询zstack数据库获取三层网络信息 + // 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(); @@ -263,7 +274,7 @@ public class TfL3Network extends L3BasicNetwork { sugonSdnController.deleteL3HostRoute(l3Network, msg,new Completion(msg){ @Override public void success() { - // 执行zstack逻辑 + // zstack business processing TfL3Network.super.handleMessage(msg); // bus.publish(evt); } @@ -281,4 +292,33 @@ public class TfL3Network extends L3BasicNetwork { } } + private void procReservedIP(APIAddIpRangeByNetworkCidrMsg msg){ + SubnetUtils.SubnetInfo subnetInfo = getSubnetInfo(new SubnetUtils(msg.getNetworkCidr())); + // Reserved for service + String servIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getLowAddress())+1); + // Reserved for edge + String edgeIp = subnetInfo.getHighAddress(); + // Get IP Range + IpRangeVO ipRangeVO = Q.New(IpRangeVO.class).eq(IpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()).find(); + // Set Used Ip + UsedIpVO servIpInfo = new UsedIpVO(); + servIpInfo.setUuid(Platform.getUuid()); + servIpInfo.setIpRangeUuid(ipRangeVO.getUuid()); + servIpInfo.setL3NetworkUuid(ipRangeVO.getL3NetworkUuid()); + servIpInfo.setIp(servIp); + servIpInfo.setIpInLong(NetworkUtils.ipv4StringToLong(servIp)); + servIpInfo.setGateway(ipRangeVO.getGateway()); + servIpInfo.setNetmask(ipRangeVO.getNetmask()); + servIpInfo.setIpVersion(IPv6Constants.IPv4); + servIpInfo.setLastOpDate(ipRangeVO.getLastOpDate()); + servIpInfo.setCreateDate(ipRangeVO.getCreateDate()); + dbf.persist(servIpInfo); + UsedIpVO edgeIpInfo = new UsedIpVO(); + BeanUtils.copyProperties(servIpInfo,edgeIpInfo); + edgeIpInfo.setUuid(Platform.getUuid()); + edgeIpInfo.setIp(edgeIp); + edgeIpInfo.setIpInLong(NetworkUtils.ipv4StringToLong(edgeIp)); + dbf.persist(edgeIpInfo); + } + }