Bug 5077: Codes break the security rules
[nemo.git] / nemo-tools / sandbox / src / main / java / org / opendaylight / nemo / tool / sandbox / models / Network.java
1 /*
2  * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.nemo.tool.sandbox.models;
10
11 import org.json.JSONArray;
12 import org.json.JSONException;
13 import org.json.JSONObject;
14 import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
15 import org.opendaylight.nemo.tool.sandbox.utils.Config;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 /**
25  * Created by hj on 12/9/15.
26  */
27 public class Network {
28     private static Logger log = LoggerFactory.getLogger(Network.class);
29     private Map<String/*name*/, Host> hostMap;
30     private Map<String/*name*/, Switch> switchMap;
31     private Map<Connector/*External connector*/, Connector/*Connector on host*/> externalConnectorMap;
32     private List<Link> internalLinks;
33     private List<Link> links;
34
35     public Network() {
36         hostMap = new HashMap<String, Host>();
37         switchMap = new HashMap<String, Switch>();
38         links = new ArrayList<Link>();
39
40         externalConnectorMap = new HashMap<Connector, Connector>();
41         internalLinks = new ArrayList<Link>();
42     }
43
44     public void addHost(Host host) {
45         hostMap.put(host.getName(), host);
46     }
47
48     public void addSwitch(Switch sw) {
49         switchMap.put(sw.getName(), sw);
50     }
51
52     public void addLink(Link link) {
53         links.add(link);
54     }
55
56     public String execute(String name, String command) {
57         Host host = hostMap.get(name);
58         if (host != null) {
59             if (CmdExecutor.open()) {
60                 String result = CmdExecutor.sshExecute("ip netns exec " + name + " " + command);
61                 CmdExecutor.close();
62                 return result;
63             } else {
64                 return "Can not open ssh right now,please try again.";
65             }
66         }
67         return name + " " + "is not a firewall,can not execute " + command;
68     }
69
70     public void install() {
71         traversal();
72
73         for (Link link : links) {
74             link.install();
75         }
76
77         for (Node node : switchMap.values()) {
78             node.install();
79         }
80
81         for (Node node : hostMap.values()) {
82             node.install();
83         }
84     }
85
86     public void uninstall() {
87         for (Link link : links) {
88             link.uninstall();
89         }
90
91         pKill();
92
93         for (Host host : hostMap.values()) {
94             host.uninstall();
95         }
96     }
97
98     private void pKill() {
99         try {
100             CmdExecutor.sshExecute("pkill -9 ofdatapath");
101             CmdExecutor.sshExecute("pkill -9 ofprotocol");
102
103             CmdExecutor.sshExecute("pkill -9 fail-ofdatapath");
104             CmdExecutor.sshExecute("pkill -9 fail-ofprotocol");
105
106             CmdExecutor.sshExecute("pkill -9 ext-ofdatapath");
107             CmdExecutor.sshExecute("pkill -9 ext-ofprotocol");
108         } catch (Exception e) {
109
110         }
111     }
112
113     public void echoConfig() {
114         CmdExecutor.sshExecute("mkdir -p " + Config.getConfigPath());
115
116         String hosts = hostJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
117         String hostsPath = Config.getConfigPath() + "/" + Config.getConfigHostsFileName();
118         CmdExecutor.sshExecute("echo " + hosts + " > " + hostsPath);
119 //        FileUtils.write(hostsPath, hosts);
120
121         String externals = externalJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
122         String externalsPath = Config.getConfigPath() + "/" + Config.getConfigExternalsFileName();
123         CmdExecutor.sshExecute("echo " + externals + " > " + externalsPath);
124 //        FileUtils.write(externalsPath, externals);
125
126         String nodes = nodeJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
127         String nodesPath = Config.getConfigPath() + "/" + Config.getConfigNodesFileName();
128         CmdExecutor.sshExecute("echo " + nodes + " > " + nodesPath);
129 //        FileUtils.write(nodesPath, nodes);
130
131         String links = externalJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
132         String linksPath = Config.getConfigPath() + "/" + Config.getConfigLinksFileName();
133         CmdExecutor.sshExecute("echo " + links + " > " + linksPath);
134 //        FileUtils.write(linksPath,links);
135     }
136
137     private void traversal() {
138         externalConnectorMap.clear();
139         internalLinks.clear();
140
141         for (Link link : links) {
142             String leftNode = link.getSrcConnector().getNodeName();
143             String rightNode = link.getDstConnector().getNodeName();
144             if (hostMap.containsKey(leftNode) && switchMap.containsKey(rightNode)) {
145                 externalConnectorMap.put(link.getDstConnector(), link.getSrcConnector());
146             } else if (hostMap.containsKey(rightNode) && switchMap.containsKey(leftNode)) {
147                 externalConnectorMap.put(link.getSrcConnector(), link.getDstConnector());
148             } else if (switchMap.containsKey(leftNode) && switchMap.containsKey(rightNode)) {
149                 internalLinks.add(link);
150             } else {
151                 log.error("Illegal link: {}.", link);
152             }
153         }
154     }
155
156     public JSONObject nodeJsonNode() {
157         JSONObject root = new JSONObject();
158         JSONArray nodeArray = new JSONArray();
159         int index = 0;
160         try {
161             for (Switch sw : switchMap.values()) {
162                 JSONObject nodeJson = buildNodeJson(sw);
163                 if (nodeJson != null) {
164                     nodeArray.put(index, nodeJson);
165                     index++;
166                 }
167             }
168             root.put("node", nodeArray);
169             return root;
170         } catch (JSONException e) {
171             // TODO Auto-generated catch block
172             log.error(e);
173         }
174         return null;
175     }
176
177     private JSONObject buildNodeJson(Switch sw) {
178         JSONObject nodeJson = new JSONObject();
179         try {
180             String nodeId = "openflow:" + sw.getDataPathId();
181             String type = sw instanceof Router ? "router" : "switch";
182             JSONArray attributes = defaultNodeAttributes(nodeId);
183             JSONArray ports = new JSONArray();
184             int index = 0;
185             List<Connector> connectors = sw.getConnectors();
186             for (Connector connector : connectors) {
187                 JSONObject portJson = new JSONObject();
188                 String portId = nodeId + ":" + connector.getOrder();
189                 String portType = externalConnectorMap.containsKey(connector) ? "external" : "internal";
190                 JSONArray portAttributes = defaultPortAttributes(portId);
191                 portJson.put("port-id", portId);
192                 portJson.put("port-type", portType);
193                 portJson.put("attribute", portAttributes);
194                 ports.put(index, portJson);
195                 index++;
196             }
197             nodeJson.put("node-id", nodeId);
198             nodeJson.put("node-type", type);
199             nodeJson.put("attribute", attributes);
200             nodeJson.put("port", ports);
201             return nodeJson;
202         } catch (Exception e) {
203             // TODO Auto-generated catch block
204             log.error(e);
205         }
206         return null;
207     }
208
209     private JSONArray defaultNodeAttributes(String nodeId) throws JSONException {
210         JSONArray jsonArray = new JSONArray();
211         JSONObject jsonObject = new JSONObject();
212         jsonObject.put("name", "location");
213         jsonObject.put("value", nodeId);
214         jsonArray.put(0, jsonObject);
215         return jsonArray;
216     }
217
218     private JSONArray defaultPortAttributes(String portId) throws JSONException {
219         JSONArray jsonArray = new JSONArray();
220         JSONObject jsonObject = new JSONObject();
221         jsonObject.put("name", "location");
222         jsonObject.put("value", portId);
223         jsonArray.put(0, jsonObject);
224         return jsonArray;
225     }
226
227     public JSONObject externalJsonNode() {
228         JSONObject root = new JSONObject();
229         JSONArray externalMacs = new JSONArray();
230         int index = 0;
231         try {
232             for (Connector exCon : externalConnectorMap.keySet()) {
233                 Connector hostCon = externalConnectorMap.get(exCon);
234                 String hostMac = CmdExecutor.queryInterfaceMac(hostCon.getConnectorName(), hostCon.getNodeName());
235                 Switch sw = switchMap.get(exCon.getNodeName());
236                 if (hostMac != null && sw != null) {
237                     JSONObject exNode = new JSONObject();
238                     String nodeId = "openflow:" + sw.getDataPathId();
239                     String portId = nodeId + ":" + exCon.getOrder();
240
241                     exNode.put("node-id", nodeId);
242                     exNode.put("port-id", portId);
243                     exNode.put("mac-address", hostMac);
244                     externalMacs.put(index, exNode);
245                     index++;
246                 }
247             }
248             root.put("external-network-mac", externalMacs);
249             return root;
250         } catch (JSONException e) {
251             // TODO Auto-generated catch block
252             log.error(e);
253         }
254         return null;
255     }
256
257     public JSONObject hostJsonNode() {
258         JSONObject root = new JSONObject();
259         JSONArray hostArray = new JSONArray();
260         int index = 0;
261         try {
262             for (Connector exCon : externalConnectorMap.keySet()) {
263                 Connector hostCon = externalConnectorMap.get(exCon);
264                 String exConMac = CmdExecutor.queryInterfaceMac(exCon.getConnectorName());
265                 Switch sw = switchMap.get(exCon.getNodeName());
266
267                 JSONObject hostJson = new JSONObject();
268                 String hostName = hostCon.getNodeName();
269                 Host host = hostMap.get(hostName);
270                 if ( exConMac != null && sw != null && host != null) {
271                     JSONArray ipv4Array = ipAddress(hostCon);
272                     String nodeId = "openflow:" + sw.getDataPathId();
273                     String connectorId = nodeId + ":" + exCon.getOrder();
274                     hostJson.put("name", hostName);
275                     hostJson.put("id", host.getUuid());
276                     hostJson.put("type", host.getNodeType());
277                     hostJson.put("ip-addresses", ipv4Array);
278                     hostJson.put("mac-address", exConMac);
279                     hostJson.put("node-id", nodeId);
280                     hostJson.put("connector-id", connectorId);
281                     hostArray.put(index, hostJson);
282                     index++;
283                 } else {
284                     log.error("Can not put host [{}] to configuration file,exMac:{}  sw:{} id:{}.", hostName, sw);
285                 }
286             }
287             root.put("host", hostArray);
288             return root;
289         } catch (JSONException e) {
290             // TODO Auto-generated catch block
291             log.error(e);
292         }
293         return null;
294     }
295
296     private JSONArray ipAddress(Connector connector) throws JSONException {
297         JSONArray jsonArray = new JSONArray();
298         Host host = hostMap.get(connector.getNodeName());
299         if (host != null) {
300             String ipv4 = host.getIpv4(connector.getOrder());
301             if (ipv4 != null) {
302                 ipv4 = ipv4 + "/";
303                 ipv4 = ipv4.substring(0, ipv4.indexOf("/"));
304                 JSONObject jsonObject = new JSONObject();
305                 jsonObject.put("ip-address", ipv4);
306                 jsonArray.put(0, jsonObject);
307                 return jsonArray;
308             }
309         }
310         return null;
311     }
312
313     public JSONObject innerLinkJsonNode() {
314         JSONObject root = new JSONObject();
315         JSONArray linkArray = new JSONArray();
316         int index = 0;
317         try {
318             for (Link link : internalLinks) {
319                 JSONObject srcLinkNode = buildLinkNode(link.getSrcConnector());
320                 if (srcLinkNode != null) {
321                     linkArray.put(index, srcLinkNode);
322                     index++;
323                 }
324                 JSONObject dstLinkNode = buildLinkNode(link.getDstConnector());
325                 if (srcLinkNode != null) {
326                     linkArray.put(index, dstLinkNode);
327                     index++;
328                 }
329             }
330             root.put("link", linkArray);
331         } catch (JSONException e) {
332             // TODO Auto-generated catch block
333             log.error(e);
334             return null;
335         }
336         return root;
337     }
338
339     private JSONObject buildLinkNode(Connector connector) {
340         Switch sw = switchMap.get(connector.getNodeName());
341         if (sw != null) {
342             JSONObject linkNode = new JSONObject();
343             String nodeId = "openflow:" + sw.getDataPathId();
344             String linkId = nodeId + ":" + connector.getOrder();
345             try {
346                 linkNode.put("link-id", linkId);
347                 linkNode.put("metric", "1");
348                 linkNode.put("delay", "");
349                 linkNode.put("loss-rate", "");
350                 return linkNode;
351             } catch (JSONException e) {
352                 // TODO Auto-generated catch block
353                 log.error(e);
354             }
355         }
356         return null;
357     }
358 }