Commit 320ef351 authored by Elf's avatar Elf

测试成功,下发逻辑拓扑

parent 9096e9a4
...@@ -16,4 +16,8 @@ public interface ClusterService { ...@@ -16,4 +16,8 @@ public interface ClusterService {
List<String> getAllEdgeNodeIds(); List<String> getAllEdgeNodeIds();
boolean adjustClusterToEdgeNode(List<SeparatedClusterConfig> configs); boolean adjustClusterToEdgeNode(List<SeparatedClusterConfig> configs);
boolean sendLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs);
boolean adjustLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs);
} }
...@@ -24,6 +24,10 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -24,6 +24,10 @@ public class ClusterServiceImpl implements ClusterService {
= "/cluster/getEdgeNodeIds"; = "/cluster/getEdgeNodeIds";
private final static String ADJUST_CLUSTER_TO_EDGE_NODE private final static String ADJUST_CLUSTER_TO_EDGE_NODE
= "/cluster/adjustCluster"; = "/cluster/adjustCluster";
private final static String SEND_LOGIC_TOPO
= "/cluster/sendLogicTopo";
private final static String ADJUST_LOGIC_TOPO
= "/cluster/adjustLogicTopo";
@Resource @Resource
private RestTemplate restTemplate; private RestTemplate restTemplate;
...@@ -64,4 +68,28 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -64,4 +68,28 @@ public class ClusterServiceImpl implements ClusterService {
return result.getStatusCode().is2xxSuccessful(); return result.getStatusCode().is2xxSuccessful();
} }
@Override
public boolean sendLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs) {
Map<String, Object> param = new HashMap<>();
param.put("configs", configs.toArray());
ResponseEntity<Boolean> result = restTemplate.postForEntity("http://" + clientProperties.getCloudUrl() + SEND_LOGIC_TOPO, configs, Boolean.class);
return result.getStatusCode().is2xxSuccessful();
}
@Override
public boolean adjustLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs) {
Map<String, Object> param = new HashMap<>();
param.put("configs", configs.toArray());
ResponseEntity<Boolean> result = restTemplate.postForEntity("http://" + clientProperties.getCloudUrl() + ADJUST_LOGIC_TOPO, configs, Boolean.class);
return result.getStatusCode().is2xxSuccessful();
}
} }
...@@ -39,4 +39,14 @@ public class ClusterController { ...@@ -39,4 +39,14 @@ public class ClusterController {
public Boolean adjustClusterToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) { public Boolean adjustClusterToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.adjustCluster(clusterConfigs); return cloudService.adjustCluster(clusterConfigs);
} }
@RequestMapping(value = "/sendLogicTopo", method = RequestMethod.POST)
public Boolean sendLogicTopoToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.sendLogicTopo(clusterConfigs);
}
@RequestMapping(value = "/adjustLogicTopo", method = RequestMethod.POST)
public Boolean adjustLogicTopoToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.adjustLogicTopo(clusterConfigs);
}
} }
...@@ -37,4 +37,8 @@ public interface CloudService { ...@@ -37,4 +37,8 @@ public interface CloudService {
Boolean addQos(Long clusterId, String appName, String maxRate, String latency); Boolean addQos(Long clusterId, String appName, String maxRate, String latency);
boolean adjustCluster(List<SeparatedClusterConfig> clusterConfigs); boolean adjustCluster(List<SeparatedClusterConfig> clusterConfigs);
boolean sendLogicTopo(List<SeparatedClusterConfig> clusterConfigs);
boolean adjustLogicTopo(List<SeparatedClusterConfig> clusterConfigs);
} }
...@@ -21,6 +21,8 @@ public class CloudServiceImpl implements CloudService { ...@@ -21,6 +21,8 @@ public class CloudServiceImpl implements CloudService {
private static final String CREATE_CLUSTER = "/createCluster"; private static final String CREATE_CLUSTER = "/createCluster";
private static final String DELETE_CLUSTER = "/delCluster"; private static final String DELETE_CLUSTER = "/delCluster";
private static final String ADJUST_CLUSTER = "/adjustCluster"; private static final String ADJUST_CLUSTER = "/adjustCluster";
private static final String SEND_LOGICTOPO = "/sendLogicTopo";
private static final String ADJUST_LOGICTOPO = "/adjustLogicTopo";
private static final String DROP_DOCKER_NETWORK = "/dropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}"; private static final String DROP_DOCKER_NETWORK = "/dropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}";
private static final String CANCEL_DROP_DOCKER_NETWORK = "/cancelDropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}"; private static final String CANCEL_DROP_DOCKER_NETWORK = "/cancelDropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}";
private static final String REMOTE_IP_LIST_BY_APPNAME = "/getIpListByAppName?clusterId={clusterId}&appName={appName}"; private static final String REMOTE_IP_LIST_BY_APPNAME = "/getIpListByAppName?clusterId={clusterId}&appName={appName}";
...@@ -90,6 +92,46 @@ public class CloudServiceImpl implements CloudService { ...@@ -90,6 +92,46 @@ public class CloudServiceImpl implements CloudService {
return true; return true;
} }
@Override
public boolean sendLogicTopo(List<SeparatedClusterConfig> clusterConfigs) {
if(clusterConfigs == null) {
throw new RuntimeException("clusterConfig cannot be null.");
}
try {
clusterConfigs.forEach(c -> {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + c.getEdgeNodeId() + SEND_LOGICTOPO, c.getClusterConfig(), String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("send Error!");
}
LOG.info("{} send logictopo success!", c.getEdgeNodeId());
});
} catch (Exception e) {
return false;
}
return true;
}
@Override
public boolean adjustLogicTopo(List<SeparatedClusterConfig> clusterConfigs) {
if(clusterConfigs == null) {
throw new RuntimeException("clusterConfig cannot be null.");
}
try {
clusterConfigs.forEach(c -> {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + c.getEdgeNodeId() + ADJUST_LOGICTOPO, c.getClusterConfig(), String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("send Error!");
}
LOG.info("{} adjust logictopo success!", c.getEdgeNodeId());
});
} catch (Exception e) {
return false;
}
return true;
}
/** /**
* 这里的拓扑必须限定为逻辑拓扑 * 这里的拓扑必须限定为逻辑拓扑
* @param clusterConfig * @param clusterConfig
......
...@@ -13,6 +13,7 @@ import top.ninwoo.edgecenter.entity.ContainerInfo; ...@@ -13,6 +13,7 @@ import top.ninwoo.edgecenter.entity.ContainerInfo;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.IpService; import top.ninwoo.edgecenter.service.IpService;
import top.ninwoo.edgecenter.service.TopologyService; import top.ninwoo.edgecenter.service.TopologyService;
import top.ninwoo.edgecenter.service.LogicTopoService;
import top.ninwoo.utils.entity.NetworkInfo; import top.ninwoo.utils.entity.NetworkInfo;
import top.ninwoo.utils.entity.OvsBridge; import top.ninwoo.utils.entity.OvsBridge;
import top.ninwoo.utils.service.TcService; import top.ninwoo.utils.service.TcService;
...@@ -32,6 +33,9 @@ public class IndexController { ...@@ -32,6 +33,9 @@ public class IndexController {
@Autowired @Autowired
private TopologyService topologyService; private TopologyService topologyService;
@Autowired
private LogicTopoService logicTopoService;
@Autowired @Autowired
private IpService ipService; private IpService ipService;
...@@ -310,4 +314,21 @@ public class IndexController { ...@@ -310,4 +314,21 @@ public class IndexController {
return ips; return ips;
} }
//下发逻辑拓扑
@RequestMapping(value = "/sendLogicTopo", method = RequestMethod.POST)
public void sendLogicTopo(@RequestBody ClusterConfig clusterConfig) {
// 创建网络
// 使用topo创建工具
logicTopoService.creatLogicTopo(clusterConfig.getId(), clusterConfig.getTopology());
}
//修改逻辑拓扑
@RequestMapping(value = "/adjustLogicTopo", method = RequestMethod.POST)
public String adjustLogicTopo(@RequestBody ClusterConfig clusterConfig) {
// 判断id
if (clusterConfig.getId() == 0) {
return "没有设置clusterid";
}
String res1 = logicTopoService.modifyLogicTopology(clusterConfig.getId(), clusterConfig.getTopology());
return res1;
}
} }
\ No newline at end of file
package top.ninwoo.edgecenter.service;
import top.ninwoo.common.entity.ClusterConfig;
import top.ninwoo.common.entity.NetworkTopology;
import java.util.List;
//逻辑网络
public interface LogicTopoService {
//通过逻辑拓扑创造逻辑网络
void creatLogicTopo(long clusterId, NetworkTopology logictopo);
//调整逻辑网络
String modifyLogicTopology(long clusterId, NetworkTopology logictopo);
//得到逻辑拓扑
NetworkTopology getLogictopo(NetworkTopology oritopo);
}
package top.ninwoo.edgecenter.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.ninwoo.common.entity.NetworkTopology;
import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.IpService;
import top.ninwoo.edgecenter.service.LogicTopoService;
import top.ninwoo.utils.service.IptablesService;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class LogicTopoServiceImpl implements LogicTopoService {
private final static Logger LOG = LoggerFactory.getLogger(TopologyServiceImpl.class);
// 用于存储集群的拓扑
private ConcurrentHashMap<Long, NetworkTopology> clustersTopo = new ConcurrentHashMap<>();
@Value("${bs.sdn-controller.host}")
private String host;
@Value("${bs.sdn-controller.port}")
private int port;
@Autowired
ClusterService clusterService;
@Autowired
IpService ipService;
@Autowired
IptablesService iptablesService;
@Override
public void creatLogicTopo(long clusterId, NetworkTopology oldtopo) {
NetworkTopology logictopo = this.getLogictopo(oldtopo);
if (logictopo == null) {
LOG.warn("集群[" + clusterId + "]未设置网络");
return;
}
// 校验信息
String[] cNames = logictopo.getAppNames();
int[][] topo = logictopo.getTopology();
if (cNames == null || cNames.length <= 1) {
return;
}
// 这里声明:cNames中不包含ovs虚拟机,仅包含docker容器组成的逻辑拓扑
for (int i = 1; i < cNames.length; i++) {
for (int j = 0; j < i; j++) {
// 判断每一个节点的连接状态
if (topo[i][j] == 0) {
// 如果判断为0,添加IPtabale,使其断开
this.addDropIPtable(clusterId, cNames[i], cNames[j]);
}
}
}
clustersTopo.put(clusterId, logictopo);
}
@Override
public String modifyLogicTopology(long clusterId, NetworkTopology oldtopo) {
NetworkTopology logictopo = this.getLogictopo(oldtopo);
// 先进行校验
if (logictopo == null) {
return "topoloy不能为空";
}
// 获取clusterId的网络拓扑
if (!clustersTopo.containsKey(clusterId)) {
return "该集群没有设置topo";
}
NetworkTopology origTopo = this.getLogictopo(clustersTopo.get(clusterId));
// 校验topoId是否一致
if (origTopo.getTopologyId() != logictopo.getTopologyId()) {
return "不是相同的网络拓扑,无法更改";
}
// 校验成员名称是否相同
for (int i = 0; i < origTopo.getAppNames().length; i++) {
if (!origTopo.getAppNames()[i].equals(logictopo.getAppNames()[i])) {
return "App名称必须一致";
}
}
int[][] origTopoArr = origTopo.getTopology();
int[][] newTopoArr = logictopo.getTopology();
// 校验topo是否一致
if ((origTopoArr.length != newTopoArr.length)
|| (origTopoArr[0].length != newTopoArr[0].length)) {
return "拓扑大小不一致";
}
// 更新网络拓扑
for (int i = 1; i < newTopoArr.length; i++) {
for (int j = 0; j < i; j++) {
//增加新的 dropIPtable
if (origTopoArr[i][j] == 1 && newTopoArr[i][j] == 0) {
// 创建新的连接
addDropIPtable(clusterId, origTopo.getAppNames()[i], origTopo.getAppNames()[j]);
} else if (origTopoArr[i][j] == 0 && newTopoArr[i][j] == 1) {
// 删除旧的连接
addDelDropIPtable(clusterId, origTopo.getAppNames()[i], origTopo.getAppNames()[j]);
}
}
}
clustersTopo.put(clusterId, logictopo);
return "success";
}
@Override
public NetworkTopology getLogictopo(NetworkTopology oritopo) {
NetworkTopology logictopo = new NetworkTopology();
int flag = 0;
//获取appnames
for (int i = 0; i < oritopo.getAppNames().length - 1; i++) {
if (oritopo.getAppNames()[i].startsWith("br:")) {
break;
}
flag++;
}
String[] appname = new String[flag];
for(int k=0;k<flag;k++){appname[k]=oritopo.getAppNames()[k];}
logictopo.setAppNames(appname);
//获取逻辑拓扑
int[][] logicTopo = new int[flag][flag];
for (int j=1;j<flag;j++){
for (int m=0;m<j;m++){logicTopo[j][m] = oritopo.getTopology()[j][m];}
}
logictopo.setTopology(logicTopo);
logictopo.setTopologyId(oritopo.getTopologyId());
return logictopo;
}
public void addDelDropIPtable(long clusterId, String appName1, String appName2) {
//获取容器ID
Set<String> cid1 = clusterService.getContainerIdsByClusterId(clusterId, appName1);
String appID1 = ((String) cid1.toArray()[0]);
String appIP1 = ipService.getContainerIp(appID1).split("/")[0];
Set<String> cid2 = clusterService.getContainerIdsByClusterId(clusterId, appName2);
String appID2 = ((String) cid2.toArray()[0]);
String appIP2 = ipService.getContainerIp(appID2).split("/")[0];
//dropTraffic(String containerId, String sourceIp, String destinationIp)
//dropTraffic模块 容器ID 源(容器)地址 目的(容器)地址
iptablesService.cancelDropTraffic(appID1, appIP2, appIP1);
iptablesService.cancelDropTraffic(appID2, appIP1, appIP2);
}
public void addDropIPtable(long clusterId, String appName1, String appName2) {
//获取容器ID
Set<String> cid1 = clusterService.getContainerIdsByClusterId(clusterId, appName1);
String appID1 = ((String) cid1.toArray()[0]);
String appIP1 = ipService.getContainerIp(appID1).split("/")[0];
Set<String> cid2 = clusterService.getContainerIdsByClusterId(clusterId, appName2);
String appID2 = ((String) cid2.toArray()[0]);
String appIP2 = ipService.getContainerIp(appID2).split("/")[0];
//dropTraffic(String containerId, String sourceIp, String destinationIp)
//dropTraffic模块 容器ID 源(容器)地址 目的(容器)地址
iptablesService.dropTraffic(appID1, appIP2, appIP1);
iptablesService.dropTraffic(appID2, appIP1, appIP2);
}
}
...@@ -24,9 +24,9 @@ bs: ...@@ -24,9 +24,9 @@ bs:
name: random name: random
ip-prefix: 192 ip-prefix: 192
ipservice: ipservice:
ip: 192.168.31.36:23333 ip: 192.168.31.238:23333
sdn-controller: sdn-controller:
host: 127.0.0.1 host: 127.0.0.1
port: 6653 port: 6653
zookeeper: zookeeper:
url: 192.168.31.36:2181 url: 192.168.31.238:2181
...@@ -30,7 +30,7 @@ public class BisheTests { ...@@ -30,7 +30,7 @@ public class BisheTests {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>(); ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig(); SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
// TODO: 这个ID应该是从借口获取的 // TODO: 这个ID应该是从借口获取的
separatedClusterConfig.setEdgeNodeId("127.0.0.1:8081"); separatedClusterConfig.setEdgeNodeId("192.168.190.135:8081");
ClusterConfig clusterConfig = new ClusterConfig(); ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l); clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu"); clusterConfig.setOwner("joliu");
...@@ -111,4 +111,65 @@ public class BisheTests { ...@@ -111,4 +111,65 @@ public class BisheTests {
i++; i++;
} }
} }
//测试逻辑网路
@Test
public void test1() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
//需修改为下发的IP地址
separatedClusterConfig.setEdgeNodeId("192.168.190.135:8081");
ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu");
ContainerDescription containerDescription = new ContainerDescription();
containerDescription.setMode("normal");
containerDescription.setReplicas(1);
DockerContainer container = new DockerContainer();
container.setName("D1");
container.setCommand("sh");
container.setImage("joliu/networktest");
containerDescription.setDockerContainer(container);
List<ContainerDescription> cds = new ArrayList<>();
cds.add(containerDescription);
ContainerDescription dis = new ContainerDescription();
dis.setMode("normal");
dis.setReplicas(1);
DockerContainer disContainer = new DockerContainer();
disContainer.setName("D2");
disContainer.setCommand("sh");
disContainer.setImage("joliu/networktest");
dis.setDockerContainer(disContainer);
cds.add(dis);
String[] appnames = new String[]{"D1", "D2", "br:ovs"};
int[][] topology = new int[][]{
{0, 0, 0 },
{0, 0, 0 },
{1, 1, 0 }};
clusterConfig.setDockers(cds);
NetworkTopology topo = new NetworkTopology();
topo.setAppNames(appnames);
// 这个参数好像没啥用
topo.setTopologyId(11);
topo.setTopology(topology);
clusterConfig.setTopology(topo);
separatedClusterConfig.setClusterConfig(clusterConfig);
clusterConfigs.add(separatedClusterConfig);
clusterService.sendClusterConfigToEdgeNode(clusterConfigs);
clusterService.sendLogicTopoToEdgeNode(clusterConfigs);
}
//改变集群拓扑配置
private boolean adjustCluster(List<SeparatedClusterConfig> configs) {
boolean b = clusterService.adjustClusterToEdgeNode(configs);
return b;
}
} }
...@@ -27,7 +27,7 @@ public class LunWenTests { ...@@ -27,7 +27,7 @@ public class LunWenTests {
public void test1() { public void test1() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>(); ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig(); SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
separatedClusterConfig.setEdgeNodeId("127.0.0.1:8081"); separatedClusterConfig.setEdgeNodeId("192.168.190.135:8081");
ClusterConfig clusterConfig = new ClusterConfig(); ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l); clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu"); clusterConfig.setOwner("joliu");
...@@ -75,7 +75,7 @@ public class LunWenTests { ...@@ -75,7 +75,7 @@ public class LunWenTests {
public void test2() { public void test2() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>(); ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig(); SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
separatedClusterConfig.setEdgeNodeId("127.0.0.1:8081"); separatedClusterConfig.setEdgeNodeId("192.168.190.135:8081");
ClusterConfig clusterConfig = new ClusterConfig(); ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l); clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu"); clusterConfig.setOwner("joliu");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment