OpenDaylight Controller functional modules.
[controller.git] / opendaylight / web / devices / src / main / java / org / opendaylight / controller / devices / web / Devices.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, 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.controller.devices.web;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import java.util.Set;
17 import java.util.TreeMap;
18 import java.util.concurrent.ConcurrentMap;
19
20 import org.codehaus.jackson.map.ObjectMapper;
21 import org.opendaylight.controller.usermanager.IUserManager;
22 import org.opendaylight.controller.web.IOneWeb;
23 import org.springframework.security.core.context.SecurityContextHolder;
24 import org.springframework.stereotype.Controller;
25 import org.springframework.web.bind.annotation.RequestMapping;
26 import org.springframework.web.bind.annotation.RequestMethod;
27 import org.springframework.web.bind.annotation.RequestParam;
28 import org.springframework.web.bind.annotation.ResponseBody;
29 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
30 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
31 import org.opendaylight.controller.sal.authorization.UserLevel;
32 import org.opendaylight.controller.sal.core.Name;
33 import org.opendaylight.controller.sal.core.Node;
34 import org.opendaylight.controller.sal.core.NodeConnector;
35 import org.opendaylight.controller.sal.core.Tier;
36 import org.opendaylight.controller.sal.utils.GlobalConstants;
37 import org.opendaylight.controller.sal.utils.HexEncode;
38 import org.opendaylight.controller.sal.utils.ServiceHelper;
39 import org.opendaylight.controller.sal.utils.Status;
40 import org.opendaylight.controller.sal.utils.TierHelper;
41 import org.opendaylight.controller.switchmanager.ISwitchManager;
42 import org.opendaylight.controller.switchmanager.SpanConfig;
43 import org.opendaylight.controller.switchmanager.SubnetConfig;
44 import org.opendaylight.controller.switchmanager.Switch;
45 import org.opendaylight.controller.switchmanager.SwitchConfig;
46
47 import com.google.gson.Gson;
48
49 @Controller
50 @RequestMapping("/")
51 public class Devices implements IOneWeb {
52     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
53     private final String WEB_NAME = "Devices";
54     private final String WEB_ID = "devices";
55     private final short WEB_ORDER = 1;
56     private final String containerName = GlobalConstants.DEFAULT.toString();
57
58     public Devices() {
59         ServiceHelper.registerGlobalService(IOneWeb.class, this, null);
60     }
61
62     @Override
63     public String getWebName() {
64         return WEB_NAME;
65     }
66
67     @Override
68     public String getWebId() {
69         return WEB_ID;
70     }
71
72     @Override
73     public short getWebOrder() {
74         return WEB_ORDER;
75     }
76
77     @Override
78     public boolean isAuthorized(UserLevel userLevel) {
79         return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
80     }
81
82     @RequestMapping(value = "/nodesLearnt", method = RequestMethod.GET)
83     @ResponseBody
84     public DevicesJsonBean getNodesLearnt() {
85         Gson gson = new Gson();
86         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
87                 .getInstance(ISwitchManager.class, containerName, this);
88         List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
89         for (Switch device : switchManager.getNetworkDevices()) {
90             HashMap<String, String> nodeDatum = new HashMap<String, String>();
91             Node node = device.getNode();
92             SwitchConfig switchConfig = switchManager.getSwitchConfig(node.getNodeIDString());
93             Tier tier = (Tier) switchManager.getNodeProp(node,
94                     Tier.TierPropName);
95             String swName = switchConfig == null ? null : switchConfig.getNodeName();
96             nodeDatum.put("containerName", containerName);
97             nodeDatum.put("nodeName", swName);
98             nodeDatum.put("nodeId", node.getNodeIDString());
99             int tierNumber = (tier == null) ? TierHelper.unknownTierNumber
100                     : tier.getValue();
101             nodeDatum.put("tierName", TierHelper.getTierName(tierNumber)
102                     + " (Tier-" + tierNumber + ")");
103             nodeDatum.put("tier", tierNumber + "");
104             SwitchConfig sc = switchManager.getSwitchConfig(device.getNode()
105                     .getNodeIDString());
106             String modeStr = (sc != null) ? sc.getMode() : "0";
107             nodeDatum.put("mode", modeStr);
108
109             nodeDatum.put("json", gson.toJson(nodeDatum));
110             nodeDatum.put("mac",
111                     HexEncode.bytesToHexString(device.getDataLayerAddress()));
112             StringBuffer sb1 = new StringBuffer();
113             Set<NodeConnector> nodeConnectorSet = device.getNodeConnectors();
114             String nodeConnectorName;
115             String nodeConnectorNumberToStr;
116             if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
117                 Map<Short, String> portList = new HashMap<Short, String>();
118                 for (NodeConnector nodeConnector : nodeConnectorSet) {
119                     nodeConnectorNumberToStr = nodeConnector.getID().toString();
120                     Name ncName = ((Name) switchManager
121                             .getNodeConnectorProp(nodeConnector,
122                                     Name.NamePropName));
123                     nodeConnectorName = (ncName != null) ? ncName.getValue() : "";
124                     portList.put(Short.parseShort(nodeConnectorNumberToStr),
125                             nodeConnectorName);
126                 }
127                 Map<Short, String> sortedPortList = new TreeMap<Short, String>(
128                         portList);
129                 for (Entry<Short, String> e : sortedPortList.entrySet()) {
130                     sb1.append(e.getValue() + "(" + e.getKey() + ")");
131                     sb1.append("<br>");
132                 }
133             }
134             nodeDatum.put("ports", sb1.toString());
135             nodeData.add(nodeDatum);
136         }
137         DevicesJsonBean result = new DevicesJsonBean();
138         result.setNodeData(nodeData);
139         List<String> columnNames = new ArrayList<String>();
140         columnNames.add("Node ID");
141         columnNames.add("Node Name");
142         columnNames.add("Tier");
143         columnNames.add("Mac Address");
144         columnNames.add("Ports");
145         
146         result.setColumnNames(columnNames);
147         return result;
148     }
149
150     @RequestMapping(value = "/tiers", method = RequestMethod.GET)
151     @ResponseBody
152     public List<String> getTiers() {
153         return TierHelper.getTiers();
154     }
155     
156     @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
157     @ResponseBody
158     public StatusJsonBean updateLearntNode(
159             @RequestParam("nodeName") String nodeName,
160             @RequestParam("nodeId") String nodeId,
161             @RequestParam("tier") String tier,
162             @RequestParam("operationMode") String operationMode) {
163         if (!authorize(UserLevel.NETWORKADMIN)) {
164                 return unauthorizedMessage();
165         }
166         
167         StatusJsonBean resultBean = new StatusJsonBean();
168         try {
169             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
170                     .getInstance(ISwitchManager.class, containerName, this);
171             SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
172                     operationMode);
173             switchManager.updateSwitchConfig(cfg);
174             resultBean.setStatus(true);
175             resultBean.setMessage("Updated node information successfully");
176         } catch (Exception e) {
177             resultBean.setStatus(false);
178             resultBean.setMessage("Error updating node information. "
179                     + e.getMessage());
180         }
181         return resultBean;
182     }
183
184     @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
185     @ResponseBody
186     public DevicesJsonBean getStaticRoutes() {
187         Gson gson = new Gson();
188         IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
189                 .getInstance(IForwardingStaticRouting.class, containerName, this);
190         List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
191         ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
192                 .getStaticRouteConfigs();
193         if (routeConfigs == null) {
194             return null;
195         }
196         for (StaticRouteConfig conf : routeConfigs.values()) {
197             Map<String, String> staticRoute = new HashMap<String, String>();
198             staticRoute.put("name", conf.getName());
199             staticRoute.put("staticRoute", conf.getStaticRoute());
200             staticRoute.put("nextHopType", conf.getNextHopType());
201             staticRoute.put("nextHop", conf.getNextHop());
202             staticRoute.put("json", gson.toJson(conf));
203             staticRoutes.add(staticRoute);
204         }
205         DevicesJsonBean result = new DevicesJsonBean();
206         result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
207         result.setNodeData(staticRoutes);
208         return result;
209     }
210
211     @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
212     @ResponseBody
213     public StatusJsonBean addStaticRoute(
214             @RequestParam("routeName") String routeName,
215             @RequestParam("staticRoute") String staticRoute,
216             @RequestParam("nextHop") String nextHop) {
217         if (!authorize(UserLevel.NETWORKADMIN)) {
218                 return unauthorizedMessage();
219         }
220         
221         StatusJsonBean result = new StatusJsonBean();
222         try {
223             IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
224                     .getInstance(IForwardingStaticRouting.class, containerName,
225                             this);
226             StaticRouteConfig config = new StaticRouteConfig();
227             config.setName(routeName);
228             config.setStaticRoute(staticRoute);
229             config.setNextHop(nextHop);
230             Status addStaticRouteResult = staticRouting.addStaticRoute(config);
231             if (addStaticRouteResult.isSuccess()) {
232                 result.setStatus(true);
233                 result.setMessage("Static Route saved successfully");
234             } else {
235                 result.setStatus(false);
236                 result.setMessage(addStaticRouteResult.getDescription());
237             }
238         } catch (Exception e) {
239             result.setStatus(false);
240             result.setMessage("Error - " + e.getMessage());
241         }
242         return result;
243     }
244
245     @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
246     @ResponseBody
247     public StatusJsonBean deleteStaticRoute(
248             @RequestParam("routesToDelete") String routesToDelete) {
249         if (!authorize(UserLevel.NETWORKADMIN)) {
250                 return unauthorizedMessage();
251         }
252         
253         StatusJsonBean resultBean = new StatusJsonBean();
254         try {
255             IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
256                     .getInstance(IForwardingStaticRouting.class, containerName,
257                             this);
258             String[] routes = routesToDelete.split(",");
259             Status result;
260             resultBean.setStatus(true);
261             resultBean
262                     .setMessage("Successfully deleted selected static routes");
263             for (String route : routes) {
264                 result = staticRouting.removeStaticRoute(route);
265                 if (!result.isSuccess()) {
266                     resultBean.setStatus(false);
267                     resultBean.setMessage(result.getDescription());
268                     break;
269                 }
270             }
271         } catch (Exception e) {
272             resultBean.setStatus(false);
273             resultBean
274                     .setMessage("Error occurred while deleting static routes. "
275                             + e.getMessage());
276         }
277         return resultBean;
278     }
279
280     @RequestMapping(value = "/subnets", method = RequestMethod.GET)
281     @ResponseBody
282     public DevicesJsonBean getSubnetGateways() {
283         Gson gson = new Gson();
284         List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
285         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
286                 .getInstance(ISwitchManager.class, containerName, this);
287         for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
288             Map<String, String> subnet = new HashMap<String, String>();
289             subnet.put("name", conf.getName());
290             subnet.put("subnet", conf.getSubnet());
291             subnet.put("json", gson.toJson(conf));
292             subnets.add(subnet);
293         }
294         DevicesJsonBean result = new DevicesJsonBean();
295         result.setColumnNames(SubnetConfig.getGuiFieldsNames());
296         result.setNodeData(subnets);
297         return result;
298     }
299     
300     @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
301     @ResponseBody
302     public StatusJsonBean addSubnetGateways(
303             @RequestParam("gatewayName") String gatewayName,
304             @RequestParam("gatewayIPAddress") String gatewayIPAddress) {
305         if (!authorize(UserLevel.NETWORKADMIN)) {
306                 return unauthorizedMessage();
307         }
308
309         StatusJsonBean resultBean = new StatusJsonBean();
310         try {
311             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
312                     .getInstance(ISwitchManager.class, containerName, this);
313             SubnetConfig cfgObject = new SubnetConfig(gatewayName,
314                     gatewayIPAddress, new ArrayList<String>());
315             Status result = switchManager.addSubnet(cfgObject);
316             if (result.isSuccess()) {
317                 resultBean.setStatus(true);
318                 resultBean.setMessage("Added gateway address successfully");
319             } else {
320                 resultBean.setStatus(false);
321                 resultBean.setMessage(result.getDescription());
322             }
323         } catch (Exception e) {
324             resultBean.setStatus(false);
325             resultBean.setMessage(e.getMessage());
326         }
327         return resultBean;
328     }
329
330     @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
331     @ResponseBody
332     public StatusJsonBean deleteSubnetGateways(
333             @RequestParam("gatewaysToDelete") String gatewaysToDelete) {
334         if (!authorize(UserLevel.NETWORKADMIN)) {
335                 return unauthorizedMessage();
336         }
337         
338         StatusJsonBean resultBean = new StatusJsonBean();
339         try {
340             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
341                     .getInstance(ISwitchManager.class, containerName, this);
342             String[] subnets = gatewaysToDelete.split(",");
343             resultBean.setStatus(true);
344             resultBean.setMessage("Added gateway address successfully");
345             for (String subnet : subnets) {
346                 Status result = switchManager.removeSubnet(subnet);
347                 if (!result.isSuccess()) {
348                     resultBean.setStatus(false);
349                     resultBean.setMessage(result.getDescription());
350                     break;
351                 }
352             }
353         } catch (Exception e) {
354             resultBean.setStatus(false);
355             resultBean.setMessage(e.getMessage());
356         }
357         return resultBean;
358     }
359
360     @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
361     @ResponseBody
362     public StatusJsonBean addSubnetGatewayPort(
363             @RequestParam("portsName") String portsName,
364             @RequestParam("ports") String ports,
365             @RequestParam("nodeId") String nodeId) {
366         if (!authorize(UserLevel.NETWORKADMIN)) {
367                 return unauthorizedMessage();
368         }
369         
370         StatusJsonBean resultBean = new StatusJsonBean();
371         try {
372             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
373                     .getInstance(ISwitchManager.class, containerName, this);
374             Status result = switchManager.addPortsToSubnet(portsName, nodeId
375                     + "/" + ports);
376
377             if (result.isSuccess()) {
378                 resultBean.setStatus(true);
379                 resultBean
380                         .setMessage("Added ports to subnet gateway address successfully");
381             } else {
382                 resultBean.setStatus(false);
383                 resultBean.setMessage(result.getDescription());
384             }
385         } catch (Exception e) {
386             resultBean.setStatus(false);
387             resultBean.setMessage(e.getMessage());
388         }
389         return resultBean;
390     }
391
392     @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
393     @ResponseBody
394     public StatusJsonBean deleteSubnetGatewayPort(
395             @RequestParam("gatewayName") String gatewayName,
396             @RequestParam("nodePort") String nodePort) {
397         if (!authorize(UserLevel.NETWORKADMIN)) {
398                 return unauthorizedMessage();
399         }
400         
401         StatusJsonBean resultBean = new StatusJsonBean();
402         try {
403             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
404                     .getInstance(ISwitchManager.class, containerName, this);
405             Status result = switchManager.removePortsFromSubnet(gatewayName,
406                     nodePort);
407
408             if (result.isSuccess()) {
409                 resultBean.setStatus(true);
410                 resultBean
411                         .setMessage("Deleted port from subnet gateway address successfully");
412             } else {
413                 resultBean.setStatus(false);
414                 resultBean.setMessage(result.getDescription());
415             }
416         } catch (Exception e) {
417             resultBean.setStatus(false);
418             resultBean.setMessage(e.getMessage());
419         }
420         return resultBean;
421     }
422
423     @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
424     @ResponseBody
425     public DevicesJsonBean getSpanPorts() {
426         Gson gson = new Gson();
427         List<String> spanConfigs_json = new ArrayList<String>();
428         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
429                 .getInstance(ISwitchManager.class, containerName, this);
430         for (SpanConfig conf : switchManager.getSpanConfigList()) {
431             spanConfigs_json.add(gson.toJson(conf));
432         }
433         ObjectMapper mapper = new ObjectMapper();
434         List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
435         for (String config_json : spanConfigs_json) {
436             try {
437                 @SuppressWarnings("unchecked")
438                 Map<String, String> config_data = mapper.readValue(config_json,
439                         HashMap.class);
440                 Map<String, String> config = new HashMap<String, String>();
441                 for (String name : config_data.keySet()) {
442                     config.put(name, config_data.get(name));
443                     // Add switch name value (non-configuration field)
444                     config.put("nodeName",
445                             getNodeName(config_data.get("nodeId")));
446                 }
447                 config.put("json", config_json);
448                 spanConfigs.add(config);
449             } catch (Exception e) {
450                 // TODO: Handle the exception.
451             }
452         }
453         DevicesJsonBean result = new DevicesJsonBean();
454         result.setColumnNames(SpanConfig.getGuiFieldsNames());
455         result.setNodeData(spanConfigs);
456         return result;
457     }
458
459     @RequestMapping(value = "/nodeports")
460     @ResponseBody
461     public Map<String, Object> getNodePorts() {
462         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
463                 .getInstance(ISwitchManager.class, containerName, this);
464         if (switchManager == null)
465             return null;
466
467         Map<String, Object> nodes = new HashMap<String, Object>();
468         Map<Short, String> port;
469
470         for (Switch node : switchManager.getNetworkDevices()) {
471             port = new HashMap<Short, String>(); // new port
472             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
473
474             if (nodeConnectorSet != null)
475                 for (NodeConnector nodeConnector : nodeConnectorSet) {
476                     String nodeConnectorName = ((Name) switchManager
477                             .getNodeConnectorProp(nodeConnector,
478                                     Name.NamePropName)).getValue();
479                     port.put((Short) nodeConnector.getID(), nodeConnectorName
480                             + "(" + nodeConnector.getID() + ")");
481                 }
482
483             nodes.put(node.getNode().toString(), port);
484         }
485
486         return nodes;
487     }
488
489     @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
490     @ResponseBody
491     public StatusJsonBean addSpanPort(@RequestParam("jsonData") String jsonData) {
492         if (!authorize(UserLevel.NETWORKADMIN)) {
493                 return unauthorizedMessage();
494         }
495         
496         StatusJsonBean resultBean = new StatusJsonBean();
497         try {
498             Gson gson = new Gson();
499             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
500                     .getInstance(ISwitchManager.class, containerName, this);
501             SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
502             Status result = switchManager.addSpanConfig(cfgObject);
503             if (result.isSuccess()) {
504                 resultBean.setStatus(true);
505                 resultBean.setMessage("SPAN Port added successfully");
506             } else {
507                 resultBean.setStatus(false);
508                 resultBean.setMessage(result.getDescription());
509             }
510         } catch (Exception e) {
511             resultBean.setStatus(false);
512             resultBean.setMessage("Error occurred while adding span port. "
513                     + e.getMessage());
514         }
515         return resultBean;
516     }
517
518     @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
519     @ResponseBody
520     public StatusJsonBean deleteSpanPorts(
521             @RequestParam("spanPortsToDelete") String spanPortsToDelete) {
522         if (!authorize(UserLevel.NETWORKADMIN)) {
523                 return unauthorizedMessage();
524         }
525         
526         StatusJsonBean resultBean = new StatusJsonBean();
527         try {
528             Gson gson = new Gson();
529             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
530                     .getInstance(ISwitchManager.class, containerName, this);
531             String[] spans = spanPortsToDelete.split("###");
532             resultBean.setStatus(true);
533             resultBean.setMessage("SPAN Port(s) deleted successfully");
534             for (String span : spans) {
535                 if (!span.isEmpty()) {
536                     SpanConfig cfgObject = gson
537                             .fromJson(span, SpanConfig.class);
538                     Status result = switchManager.removeSpanConfig(cfgObject);
539                     if (!result.isSuccess()) {
540                         resultBean.setStatus(false);
541                         resultBean.setMessage(result.getDescription());
542                         break;
543                     }
544                 }
545             }
546         } catch (Exception e) {
547             resultBean.setStatus(false);
548             resultBean.setMessage("Error occurred while deleting span port. "
549                     + e.getMessage());
550         }
551         return resultBean;
552     }
553
554     private String getNodeName(String nodeId) {
555         String nodeName = nodeId;
556         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
557                 .getInstance(ISwitchManager.class, containerName, this);
558
559         Node node = Node.fromString(nodeId);
560         if (switchManager != null) {
561             SwitchConfig config = switchManager.getSwitchConfig(node
562                     .getNodeIDString());
563             if (config != null) {
564                 nodeName = config.getNodeName();
565             }
566         }
567         return nodeName;
568     }
569
570     /**
571      * Is the operation permitted for the given level
572      * 
573      * @param level
574      */
575     private boolean authorize(UserLevel level) {
576         IUserManager userManager = (IUserManager) ServiceHelper
577                 .getGlobalInstance(IUserManager.class, this);
578         if (userManager == null) {
579                 return false;
580         }
581         
582         String username = SecurityContextHolder.getContext().getAuthentication().getName();
583         UserLevel userLevel = userManager.getUserLevel(username);
584         if (userLevel.toNumber() <= level.toNumber()) {
585                 return true;
586         }
587         return false;
588     }
589     
590     private StatusJsonBean unauthorizedMessage() {
591         StatusJsonBean message = new StatusJsonBean();
592         message.setStatus(false);
593         message.setMessage("Operation not authorized");
594         return message;
595     }
596
597 }