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